home *** CD-ROM | disk | FTP | other *** search
Text File | 2001-01-26 | 60.3 KB | 1,779 lines |
- ## -*-Tcl-*- (nowrap)
- # ==========================================================================
- # Statistical Modes - an extension package for Alpha
- #
- # FILE: "spssMode.tcl"
- # created: 01/15/00 {07:15:32 pm}
- # last update: 01/26/01 {12:21:56 pm}
- # Description:
- #
- # For SPSS syntax files.
- #
- # Author: Craig Barton Upright
- # E-mail: <cupright@princeton.edu>
- # mail: Princeton University, Department of Sociology
- # Princeton, New Jersey 08544
- # www: <http://www.princeton.edu/~cupright>
- #
- # -------------------------------------------------------------------
- #
- # Copyright (c) 2000-2001 Craig Barton Upright
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- #
- # ==========================================================================
- ##
-
- # ===========================================================================
- #
- # ◊◊◊◊ Initialization of SPSS mode ◊◊◊◊ #
- #
-
- alpha::mode SPSS 2.1.1 spssMenu {*.sps *.spss *.spp} {
- spssMenu electricReturn electricTab electricBraces
- } {
- # We require 7.4b21 for prefs handling.
- alpha::package require -loose AlphaTcl 7.4b21
- addMenu spssMenu "SPSS" SPSS
- set unixMode(spss) {SPSS}
- set modeCreator(SPSS) {SPSS}
- } uninstall {
- this-file
- } help {
- file "Statistical Modes Help"
- } maintainer {
- "Craig Barton Upright" <cupright@princeton.edu>
- <http://www.princeton.edu/~cupright/>
- }
-
- hook::register quitHook SPSS::quitHook
-
- proc spssMenu {} {}
-
- proc spssMode.tcl {} {}
-
- namespace eval SPSS {}
-
- # ===========================================================================
- #
- # ◊◊◊◊ Setting SPSS mode variables ◊◊◊◊ #
- #
-
- # Removing obsolete preferences from earlier versions.
-
- set oldvars {
- addArguments addSymbols argumentColor don'tRemindMe electricTab
- functionColor keywordColor spssHelp
- }
-
- foreach oldvar $oldvars {prefs::removeObsolete SPSSmodeVars($oldvar)}
-
- unset oldvar oldvars
-
- # ===========================================================================
- #
- # Standard preferences recognized by various Alpha procs
- #
-
- newPref var fillColumn {75} SPSS
- newPref var leftFillColumn {0} SPSS
- newPref var prefixString {* } SPSS
- newPref var wordBreak {[-a-zA-Z0-9\.]+} SPSS
- newPref var wordBreakPreface {[^-a-zA-Z0-9\.]} SPSS
- newPref flag wordWrap {0} SPSS
-
- # ===========================================================================
- #
- # Flag preferences
- #
-
- # ===========================================================================
- #
- # Preferences to allow user to include additional commands, arguments, and
- # symbols through the Mode Preferences dialog.
- #
-
- newPref flag autoMark {0} SPSS {SPSS::rebuildMenu spssMenu}
-
- # Indent all continued commands, indicated by the lack of a period at
- # the end of a line, by the full indentation amount rather than half.
- newPref flag fullIndent {1} SPSS {SPSS::rebuildMenu spssMenu}
-
- # By default command double-click will send a command to on-line help, and
- # option double-click sends a command to the local SPSS application.
- # Check this box to switch these key combinations.
- newPref flag localHelp {0} SPSS {SPSS::rebuildMenu spssHelp}
-
- # Check this box if your keyboard does not have a "Help" key. This will
- # change some of the menu's key bindings.
- newPref flag noHelpKey {0} SPSS {SPSS::rebuildMenu spssHelp}
-
- # Set the list of flag preferences which can be changed in the menu.
-
- set SPSSPrefsInMenu [list \
- "localHelp" \
- "noHelpKey" \
- "fullIndent" \
- ]
-
- # ===========================================================================
- #
- # Variable preferences
- #
-
- # Enter additional SPSS keywords to be colorized. These will also be
- # included in electric completions.
- newPref var addCommands {} SPSS {SPSS::colorizeSPSS}
-
- # Select the statistical application to be used.
- newPref var application {SPSS} SPSS {SPSS::rebuildMenu spssMenu} [list PSPP SPSS]
-
- # The "PSPP Home Page" menu item will send this url to your browser.
- newPref url psppHomePage {http://www.gnu.org/software/pspp/} SPSS
-
- # Click on "Set" to find the local PSPP application.
- newPref sig psppSig {} SPSS
-
- # Command double-clicking on an SPSS keyword will send it to this url
- # for a help reference page.
- newPref url helpUrl {http://www.gnu.org/cgi-bin/htsearch?words=pspp%2C+} SPSS
-
- # The "SPSS Home Page" menu item will send this url to your browser.
- newPref url spssHomePage {http://www.spss.com/} SPSS
-
- # Click on "Set" to find the local SPSS application.
- newPref sig spssSig {SPSS} SPSS
-
- # ===========================================================================
- #
- # Color preferences
- #
- # Nomenclature notes:
- #
- # SPSS does a lousy job of naming things, or at least is more than willing
- # to give a keyword (as in SPSS keyword) the same name as a function,
- # statement, subcommand or command. There's little point in trying to
- # distinguish amongst all of this with different colors, because it just
- # won't work. Instead, I'm just putting them all in one list, calling them
- # all "commands" and reminiscing about the days when S-Plus was my stats
- # package of choice. The nomenclature of SPSS is only one of its several
- # limitations.
- #
-
- # See the Statistical Modes Help file for an explanation of these different
- # categories, and lists of keywords.
- newPref color commandColor {blue} SPSS {SPSS::colorizeSPSS}
- newPref color commentColor {red} SPSS {stringColorProc}
- newPref color operatorColor {blue} SPSS {SPSS::colorizeSPSS}
- newPref color stringColor {green} SPSS {stringColorProc}
-
- # The color of symbols such as +, -, /, etc.
- newPref color symbolColor {magenta} SPSS {SPSS::colorizeSPSS}
-
- regModeKeywords -e {*} -b {/*} {*/} \
- -c $SPSSmodeVars(commentColor) \
- -s $SPSSmodeVars(stringColor) SPSS {}
-
- # ===========================================================================
- #
- # Flag Flip
- #
- # Called by menu items, change the value of flag preferences.
- #
-
- proc SPSS::flagFlip {pref} {
-
- global mode SPSSmodeVars
-
- set SPSSmodeVars($pref) [expr {$SPSSmodeVars($pref) ? 0 : 1}]
- set oldMode $mode
- set mode "SPSS"
- synchroniseModeVar $pref $SPSSmodeVars($pref)
- set mode $oldMode
- if {$SPSSmodeVars($pref)} {
- set end "on"
- } else {
- set end "off"
- }
- message "The \"$pref\" preference is now $end."
- }
-
- # ===========================================================================
- #
- # Comment Character variables for Comment Line / Paragraph / Box menu items.
- #
-
- set SPSS::commentCharacters(General) [list "* "]
- set SPSS::commentCharacters(Paragraph) [list "** " " **" " * "]
- set SPSS::commentCharacters(Box) [list "*" 1 "*" 1 "*" 3]
-
- # ===========================================================================
- #
- # ◊◊◊◊ Keyword Dictionaries ◊◊◊◊ #
- #
-
- # Making sure that SPSSUserCommands exists.
- # This will be over-ridden if it is loaded from a ${mode}Prefs.tcl file.
- #
-
- set SPSSUserCommands ""
-
- # ===========================================================================
- #
- # ◊◊◊◊ SPSS Commands ◊◊◊◊ #
- #
-
- set SPSSCommands {
- a absolute add adevice adjred afreq after aggregate aic ainds align
- alpha alsal analysis anova append approximate ar area ascii asresid
- association automatic autorecode avalue average averf avonly awymmetic
- backward badcorr barchart bart base basis baverage bcon bcov begin
- beuclid binomial blank blanks blksize blwmn bmdp bmpd boick bootstrap
- both boundary box boxm brau break breakdown brief brkspace bseuclid
- bshape bstep btukey buffno calculate call categorical case casenum
- cases cc cdfnorm cellinfo cells center centroid cfvar cha chalign
- charend chdpace chebychev chicdf chisq chol choropleth ci cinterval
- ckder clabels classify classplot clear clnr cluster cmax cmin cnames
- cnlr cochran code colconf collect collin collinearity colspace column
- columnwise combined comm comment compare complete compositional
- compressed compression compute concat condense condensed condition
- conditional config constrained content contents continued contour
- contrast convert cook copy cor corff corr correlations cosine count cov
- covariances covariates cpi criteria crossbreak crosstabs crshtol cssq
- csum ctime.days ctime.hours ctime.minures cufreq cupct curpoints cusum
- cutoff cweight d data date.dmy date.mdy date.moyr date.qur date.wkyr
- date.yrday default define delta dendrogram density dependent
- derivatives desc descending descending descriptives design det dev
- deviation dfbeta dfe dfreq diag diagonal dice dictionary difference
- digits dimenrdimens directions discrim discriminant disper display
- distance divide document documents doend dollar double down draw dresid
- drop dummy duncan duplicate durbin dvalue ebcdid econverge edit effects
- efsize eigen eject else enclose end enter eof eps equamax error errors
- estim eta euclid eval every exact examine exclude execute expected
- experimental export external extraction f facilities factor fgtmlr
- fieldnames file files fin fin finish first first fixed flip flt fnames
- footnote for formats fortran forward fout fpair fprecision freq
- frequencies friedman from frspace fscore fstep ftolerance full
- functions gamma gcmdfile gcov gdata gdevice gemscal get gg ginv gls
- gmemory graph great gresid grouped groups groups groupwise gsch guttman
- hamann handle harmonic hazard hbar head header helmert help hf hicicle
- hierarchical higher highest hiloglinear histogram history hold
- homogeneity horizontal host hotelling hsize hypoth id ident if image
- import in include increment indicator individual indscal info initial
- inline input input intermed interval intervals into inv istep iter
- iterate jaccard jdate joint journal k-s k-w k1 k2 kaiser kappa keep
- kendall key keyed kmo kroneker kurtosis label labels lag lambda last
- lcon least leave left length let level lever lftolerance limit line
- linearity list listing listwise log logistic logit loglinear logsurv
- loop loss lower lowest lpad lpi lresid lsd lstolerance ltrim m-wm
- macros magic mahal make manova manual map match matrix maxorders
- maxsteps mconvert mde mean means merge mestimates method missing mixed
- mode model more moses mprint mrgroup msave mssq msum mult multiple
- multiply multipunch multiv multivariate muplus mwithin mxerrs mxloops
- mxwarns n n_matrix n_scalar n_vector name names naname nanames natres
- navallabs ncol ncomp negative nested new newnames newnames newpage
- nftolerance ngt nin nlr nlr nmiss no nobox nocatlabs nodiagonal noend
- noexpand noindex noinitial nokaiser nolabels nolist nominal none
- nonmissing nonpar noorigin noprint normal normplot normprob norotate
- nosig nostep notable noulb noupdate novalues nowarn npar nrow ntiles nu
- null nulline number numbered numeric numiss nvalid oblimin occurs
- ochaiai of off offexpand offset omeans onepage onetail oneway oneway
- oneway onexpand optimal options optolerance ordered ordinal origin
- orthonorm osiris other out outfile outliers output outs overlay
- overview p pa1 pa2 paf page paired pairs pairwise parall parallel
- parameters partial partialplot partition pattern pc pcomps pcon pct
- pearson percent percentiles pgroup pgt ph2 phi pie pin pin plain plot
- plt pmeans point polynomial pool pooled positional pout power pred
- preserve presorted previous print printback priors prism probit
- procedure procedures proportion prox proximities ptile pyramid q
- quartiles quartimax quick quick quick quote r radial range ranges rank
- ration raw rcon rconverge recode rectangular reduncancy reformat reg
- regression regwgt release reliability remove rename repeat repeating
- replace report reread rescale reshape resid residual residuals response
- responses restore results reverse rfraction rfraction right rindex risk
- rlabels rmax rmin rmp rnames rnkorder rotate rotation row rowconf rows
- rpad rr rssq rsum rt rtrim runs sample sas saslib savage save scale
- scan scatterplot schedule scheffe scompression scratch scss sd sdresid
- seed sekurt select semean separate serdiag serial ses seskew set
- seuclid shape show sig sign signif significance simple since single
- singledf size skewness skip sm snames snk solve sort space space
- spearman special split spread spred spss sresid sscon sscp sstype
- stacked stan standardize starts statistics status stddev step stepdown
- steplimit stepwise stimwght stressmin strictparallel string strings
- substr substring subtitle subtract sum summary sumspace survival sval
- svd sweep symbols symmetric sysmix t t-test table tables tail tape tb1
- tb2 tbfonts tcdf tcov temporary terminal test tests then ties tiestore
- time time.days time.hms title tokens tolerance total transformations
- translate tspace tukey twotail type type uc uls unclassified
- uncompressed unconditional undefined underscore uniform unique univ
- univariate univf unnumbered unquote unselected up upcase update validn
- value values var variable variables variance varimax vars vector
- vertical vicile view vin vs vsize w-w ward warn waverage weight width
- wilcoxon wild workfile write wsdesign wsfactors xdate.date xdate.hour
- xdate.jday xdate.mday xdate.minute xdate.month xdate.quarter
- xdate.second xdate.tday xdate.time xdate.week xdate.wkday xdate.year
- xmdend xprod xsave xsort xtx y yes yrmoda z z zcorr zpp zpred zresid
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ SPSS Functions ◊◊◊◊ #
- #
-
- set SPSSFunctions {
- abs arsin artan cos exp lg10 ln mod rnd sin sqrt trunc
- }
-
-
- # ===========================================================================
- #
- # ◊◊◊◊ SPSS Operators ◊◊◊◊ #
- #
-
- set SPSSOperators {
- all and by eq ge gt into le lt ne not or .por .sav .sps thru to with
- xls
- }
-
- # ===========================================================================
- #
- # Colorize SPSS.
- #
- # Set all keyword lists, and colorize.
- #
- # Could also be called in a <mode>Prefs.tcl file
- #
-
- proc SPSS::colorizeSPSS {{pref ""}} {
-
- global SPSSmodeVars SPSSCommands SPSSFunctions SPSSOperators SPSSUserCommands
-
- global SPSSlowerCaseCommands SPSSupperCaseCommands
- global SPSSlowerCaseFunctions SPSSupperCaseFunctions
- global SPSSlowerCaseCmds SPSScmds
-
- # Create the list of all keywords for completions. SPSS keywords
- # are not case-sensitive. To allow for different user styles,
- # we'll include lower case commands as well as ALL CAPS.
- message "Creating ALL CAP commands for SPSS mode …"
- # Commands only
- set SPSSlowerCaseCommands [concat \
- $SPSSCommands $SPSSmodeVars(addCommands) $SPSSUserCommands \
- ]
- set SPSSupperCaseCommands [string toupper $SPSSlowerCaseCommands]
- # Functions only
- set SPSSlowerCaseFunctions $SPSSFunctions
- set SPSSupperCaseFunctions [string toupper $SPSSlowerCaseFunctions]
-
- set SPSSlowerCaseCmds [lsort [lunique [concat \
- $SPSSlowerCaseCommands $SPSSlowerCaseFunctions \
- ]]]
-
- # SPSScmds
- set SPSScmds [lsort [lunique [concat \
- $SPSSlowerCaseCommands $SPSSupperCaseCommands $SPSSlowerCaseFunctions \
- $SPSSupperCaseFunctions \
- ]]]
- message ""
-
- # Commands
- regModeKeywords -a -k $SPSSmodeVars(commandColor) SPSS $SPSScmds
-
- # Operators
- regModeKeywords -a \
- -k $SPSSmodeVars(operatorColor) SPSS $SPSSOperators
-
- # Symbols
- regModeKeywords -a \
- -k $SPSSmodeVars(symbolColor) SPSS {|} \
- -i "+" -i "-" -i "_" -i "\\" \
- -I $SPSSmodeVars(symbolColor)
-
- if {$pref != ""} {refresh}
- }
-
- # Call this now.
-
- SPSS::colorizeSPSS
-
- # ===========================================================================
- #
- # Reload Completions.
- #
- # This is now an obsolete proc.
- #
-
- proc SPSS::reloadCompletions {} {
- alertnote "\"SPSS::reloadCompletions\" is an obsolete proc.\
- It should be removed from your SPSSPrefs.tcl file."
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Key Bindings, Electrics ◊◊◊◊ #
- #
-
- # Known bug: Key-bindings from other global menus might conflict with those
- # defined in the SPSS menu. This will help ensure that this doesn't happen.
-
- Bind 'n' <sz> {SPSS::nextCommand} SPSS
- Bind 'p' <sz> {SPSS::prevCommand} SPSS
- Bind 's' <sz> {SPSS::selectCommand} SPSS
- Bind 'c' <sz> {SPSS::copyCommand} SPSS
-
- Bind 'i' <cz> {SPSS::reformatCommand} SPSS
-
- Bind '\)' {SPSS::electricRight "\)"} SPSS
-
- # For those that would rather use arrow keys to navigate:
-
- Bind up <sz> {SPSS::prevCommand 0 0} SPSS
- Bind left <sz> {SPSS::prevCommand 0 1} SPSS
- Bind down <sz> {SPSS::nextCommand 0 0} SPSS
- Bind right <sz> {SPSS::nextCommand 0 1} SPSS
-
- # ===========================================================================
- #
- # SPSS Carriage Return
- #
- # Inserts a carriage return, and indents properly.
- #
-
- proc SPSS::carriageReturn {} {
-
- global SPSSmodeVars
-
- if {[isSelection]} {
- deleteSelection
- }
- set pos1 [lineStart [getPos]]
- set pos2 [getPos]
- if {[regexp {^([\t ])*(\}|\))} [getText $pos1 $pos2]]} {
- createTMark temp $pos2
- catch {bind::IndentLine}
- gotoTMark temp ; removeTMark temp
- }
- insertText "\r"
- catch {bind::IndentLine}
- }
-
- # ===========================================================================
- #
- # SPSS Electric Left, Right
- #
- # Adapted from "tclMode.tcl"
- #
-
- proc SPSS::electricLeft {} {
-
- if {[literalChar]} {
- typeText "\{"
- return
- }
- set pat "\}\[ \t\r\n\]*(else(if)?)\[ \t\r\n\]*\$"
- set pos [getPos]
- if { [set result [findPatJustBefore "\}" $pat $pos word]] == "" } {
- insertText "\{"
- return
- }
- # we have an if/else(if)/else
- switch -- $word {
- "else" {
- deleteText [lindex $result 0] $pos
- elec::Insertion "\} $word \{\r\t••\r\}\r••"
- }
- "elseif" {
- deleteText [lindex $result 0] $pos
- elec::Insertion "\} $word \{••\} \{\r\t••\r\}\r••"
- }
- }
- }
-
- proc SPSS::electricRight {{char "\}"}} {
-
- if {[literalChar]} {
- typeText $char
- return
- }
- set pos [getPos]
- typeText $char
- if {![regexp {[^ \t]} [getText [lineStart $pos] $pos]]} {
- set pos [lineStart $pos]
- createTMark temp [getPos]
- catch {bind::IndentLine}
- gotoTMark temp ; removeTMark temp
- bind::CarriageReturn
- }
- if {[catch {blink [matchIt $char [pos::math $pos - 1]]}]} {
- beep ; message "No matching $char !!"
- }
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Indentation ◊◊◊◊ #
- #
- # SPSS::correctIndentation is necessary for Smart Paste, and returns the
- # correct level of indentation for the current line. SPSS::indentLine uses
- # this level to indent the current line.
- #
- # We have two level of indentation in SPSS, for the continuation of
- # commands, in which case we simply indent to the amount of the SPSS mode
- # variable indentationAmount, and for nested braces.
- #
- # In SPSS::correctIndentation, we grab the previous non-commented line,
- # remove all of the characters besides braces and quotes, and then convert
- # it all to a list to be evaluated. Braces contained within quotes, as
- # well as literal characters, should all be ignored and the remaining
- # braces are used to determine the correct level of nesting.
- #
-
- proc SPSS::indentLine {{pos ""}} {
-
- if {$pos == ""} {set pos [getPos]}
- # Get details of current line.
- set posBeg [lineStart [getPos]]
- set text [getText $posBeg [nextLineStart $posBeg]]
- regexp {^[ \t]*} $text white
- set posNext1 [pos::math $posBeg + [string length $white]]
- set posNext2 [pos::math $posNext1 + 1]
- if {[pos::compare $posNext2 > [maxPos]]} {
- set posNext2 [maxPos]
- }
- # Determine the correct level of indentation for this line, given the
- # next character.
- set lwhite [SPSS::correctIndentation $pos [getText $posNext1 $posNext2]]
- set lwhite [text::indentOf $lwhite]
- if {$white != $lwhite} {
- replaceText $posBeg $posNext1 $lwhite
- }
- goto [pos::math $posBeg + [string length $lwhite]]
- }
-
- proc SPSS::correctIndentation {pos {next ""}} {
-
- global mode indent_amounts SPSSmodeVars
-
- if {$mode == "SPSS"} {
- set continueIndent [expr {$SPSSmodeVars(fullIndent) + 1}]
- } else {
- set continueIndent 2
- }
-
- set posBeg [lineStart $pos]
- # Get information about this line, previous line ...
- set thisLine [SPSS::getCommandLine $posBeg 1 1]
- set prevLine1 [SPSS::getCommandLine [pos::math $posBeg - 1] 0 1]
- set prevLine2 [SPSS::getCommandLine [pos::math [lindex $prevLine1 0] - 1] 0 1]
- set lwhite [lindex $prevLine1 1]
- # If we have a previous line ...
- if {[pos::compare [lindex $prevLine1 0] != $posBeg]} {
- set pL1 [string trim [lindex $prevLine1 2]]
- # Indent if the last line did not terminate the command.
- if {![regexp {\.([\t ]?)$} $pL1]} {
- incr lwhite $indent_amounts($continueIndent)
- }
- # Check to make sure that the previous command was not itself a
- # continuation of the line before it.
- if {[pos::compare [lindex $prevLine1 0] != [lindex $prevLine2 0]]} {
- set pL2 [string trim [lindex $prevLine2 2]]
- if {![regexp {\.([\t ]?)$} $pL2]} {
- incr lwhite $indent_amounts(-$continueIndent)
- }
- }
- # Find out if there are any unbalanced {,},(,) in the last line.
- regsub -all {[^ \{\}\(\)\"\*\/\\]} $pL1 { } line
- # Remove all literals.
- regsub -all {\\\{|\\\}|\\\(|\\\)|\\\"|\\\*|\\\/} $line { } line
- regsub -all {\\} $line { } line
- # Remove everything surrounded by quotes.
- regsub -all {\"([^\"]+)\"} $line { } line
- regsub -all {\"} $line { } line
- # Remove everything surrounded by bracketed comments.
- regsub -all {/\*([^\*/]+)\*/} $line { } line
- # Now turn all braces into 2's and -2's
- regsub -all {\{|\(} $line { 2 } line
- regsub -all {\}|\)} $line { -2 } line
- # This list should now only contain 2's and -2's.
- foreach i $line {
- if {$i == "2" || $i == "-2"} {incr lwhite $indent_amounts($i)}
- }
- # Did the last line start with a lone \) or \} ? If so, we want to
- # keep the indent, and not make call it an unbalanced line.
- if {[regexp {^[\t ]*(\}|\))} $pL1]} {
- incr lwhite $indent_amounts(2)
- }
- }
- # If we have a current line ...
- if {[pos::compare [lindex $thisLine 0] == $posBeg]} {
- # Reduce the indent if the first non-whitespace character of this
- # line is ) or \}.
- set tL [lindex $thisLine 2]
- if {$next == "\}" || $next == ")" || [regexp {^[\t ]*(\}|\))} $tL]} {
- incr lwhite $indent_amounts(-2)
- }
- }
- # Now we return the level to the calling proc.
- return [expr {$lwhite > 0 ? $lwhite : 0}]
- }
-
- # ===========================================================================
- #
- # Get Command Line
- #
- # Find the next/prev command line relative to a given position, and return
- # the position in which it starts, its indentation, and the complete text
- # of the command line. If the search for the next/prev command fails,
- # return an indentation level of 0.
- #
- # We have the luxury here of ignore any previous/next commented lines.
- #
-
- proc SPSS::getCommandLine {pos {direction 1} {ignoreComments 1}} {
-
- if {$ignoreComments} {
- set pat {^[\t ]*[^\t\r\n\*/ ]}
- } else {
- set pat {^[\t ]*[^\t\r\n ]}
- }
- set posBeg [pos::math [lineStart $pos] - 1]
- if {[pos::compare $posBeg < [minPos]]} {
- set posBeg [minPos]
- }
- set lwhite 0
- if {![catch {search -f $direction -r 1 $pat $pos} match]} {
- set posBeg [lindex $match 0]
- set lwhite [posX [pos::math [lindex $match 1] - 1]]
- }
- set posEnd [pos::math [nextLineStart $posBeg] - 1]
- if {[pos::compare $posEnd > [maxPos]]} {
- set posEnd [maxPos]
- }
- return [list $posBeg $lwhite [getText $posBeg $posEnd]]
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Command Double Click ◊◊◊◊ #
- #
- # Checks to see if the highlighted word appears in any keyword list, and if
- # so, sends the selected word to the www.SPSS.com help site.
- #
- # Control-Command double click will insert syntax information in status bar.
- # Shift-Command double click will insert commented syntax information in window.
- #
- # (The above is not yet implemented -- need to enter all of the syntax info.)
- #
-
- proc SPSS::DblClick {from to shift option control} {
-
- global SPSSmodeVars SPSScmds SPSSSyntaxMessage
-
- select $from $to
- set command [getSelect]
-
- if {[lsearch -exact $SPSScmds $command] == -1} {
- message "\"$command\" is not defined as a SPSS system keyword."
- return
- }
- # Any modifiers pressed?
- if {$control} {
- # CONTROL -- Just put syntax message in status bar window
- if {[info exists SPSSSyntaxMessage($command)]} {
- message "$SPSSSyntaxMessage($command)"
- } else {
- message "Sorry, no syntax information available for $command"
- }
- } elseif {$shift} {
- # SHIFT --Just insert syntax message as commented text
- if {[info exists SPSSSyntaxMessage($command)]} {
- endOfLine
- insertText "\r"
- insertText "$SPSSSyntaxMessage($command)"
- comment::Line
- } else {
- message "Sorry, no syntax information available for $command"
- }
- } elseif {$option && !$SPSSmodeVars(localHelp)} {
- # Now we have four possibilities, based on "option" key and the
- # preference for "local Help Only". (Local Help Only actually
- # switches the "normal" behavior of options versus not.)
- #
- # OPTION, local help isn't checked -- Send command to local application
- SPSS::localCommandHelp $command
- } elseif {$option && $SPSSmodeVars(localHelp)} {
- # OPTION, but local help is checked -- Send command for on-line help.
- SPSS::wwwCommandHelp $command
- } elseif {$SPSSmodeVars(localHelp)} {
- # No modifiers, local help is checked -- Send command to local app.
- SPSS::localCommandHelp $command
- } else {
- # No modifiers, no local help checked -- Send command for on-line
- # help. This is the "default" behavior.
- SPSS::wwwCommandHelp $command
- }
- }
-
- # ===========================================================================
- #
- # WWW Command Help
- #
- # Send command to defined url, prompting for text if necessary.
- #
-
- proc SPSS::wwwCommandHelp {{command ""}} {
-
- global SPSSmodeVars
-
- if {$command == ""} {
- set command [prompt "on-line SPSS/PSPP help for ... " [getSelect]]
- # set command [statusPrompt "on-line help for ... " ]
- }
- message "\"$command\" sent to $SPSSmodeVars(helpUrl)"
- url::execute $SPSSmodeVars(helpUrl)$command
- }
-
- # ===========================================================================
- #
- # Local Command Help
- #
- # Send command to local application, prompting for text if necessary.
- #
-
- proc SPSS::localCommandHelp {{command ""} {app ""}} {
-
- SPSS::betaMessage
-
- global SPSSmodeVars tcl_platform
-
- if {$app == ""} {
- set app $SPSSmodeVars(application)
- }
- if {$command == ""} {
- set command [prompt "local $app application help for ... " [getSelect]]
- # set command [statusPrompt "local S-Plus application help for ..." ]
- }
- set pf $tcl_platform(platform)
-
- if {$pf == "macintosh"} {
- # Make sure that the Macintosh application for the signature exists.
- if {[catch {[nameFromAppl [SPSS::sig $app]]}]} {
- SPSS::selectApplication $app
- }
- } elseif {$pf == "windows" || $pf == "unix"} {
- # Make sure that the Windows application for the signature exists.
- # We assume that this will work for unix, too.
- if {![file exists [SPSS::sig $app]]} {
- SPSS::selectApplication $app
- }
- }
- # Now we look for the actual help file.
- if {![file exists $helpFile]} {
- beep ; message "Sorry, no help file for \"$command\" was found."
- error "No help file found for \"$command\"."
- } else {
- help::openFile $helpFile
- }
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Mark File and Parse Functions ◊◊◊◊ #
- #
-
- # ===========================================================================
- #
- # SPSS Mark File
- #
- # This will return the first 35 characters from the first non-commented
- # word that appears in column 0. All other output files (those not
- # recognized) will take into account the additional left margin elements
- # added by SPSS/PSPP.
- #
-
- proc SPSS::MarkFile {{type ""}} {
-
- removeAllMarks
-
- message "Marking File …"
-
- set pos [minPos]
- set count 0
- # Figure out what type of file this is -- source, frequency, or output.
- # The variable "type" refers to a call from the SPSS menu.
- # Otherwise we try to figure out the type based on the file's suffix.
- if {$type == ""} {
- if {[win::CurrentTail] == "* SPSS Mode Example *"} {
- # Special case for Mode Examples, but only if called from
- # Marks menu. (Called from SPSS menu, "type" will over-ride.)
- set type ".sps"
- } else {
- set type [file extension [win::CurrentTail]]
- }
- }
- # Set the mark expression.
- if {$type == ".sps"} {
- # Is this a source file?
- set markExpr {^(\*\*\*[ ]|\*\*\*\*[ ])?[a-zA-Z]}
- } elseif {$type == ".freq"} {
- # Is this a frequencies file? Determining what is truly a variable
- # in SPSS output is not straightforward. This regexp is a little
- # particular, and might only apply to unix output.
- set markExpr {^.+[\r\n]+[ ]+(Valid )}
- catch {set pos [lindex [search -f 1 -m 0 -i 1 {freq} [minPos]] 0]}
- } else {
- # Assume that it's output.
- set markExpr {^[ ]+[0-9]+( )(0 )*(\*\*\*[ ]|\*\*\*\*[ ])?[a-zA-Z]}
- }
- # Now mark the file.
- while {![catch {search -f 1 -r 1 -m 0 $markExpr $pos} match]} {
- if {$type == ".freq"} {
- set posBeg [lineStart [lindex $match 0]]
- set posEnd [nextLineStart $posBeg]
- set line [string trimright [getText $posBeg $posEnd]]
- regsub {[ ]+.+$} $line {} line
- message "# of variables: [incr count]"
- } else {
- incr count
- set posBeg [lindex $match 0]
- set posEnd [nextLineStart $posBeg]
- if {[pos::compare $posEnd > [maxPos]]} {set posEnd [maxPos]}
- set line [string trimright [getText $posBeg $posEnd]]
- # Get rid of the leading " [0-9] " for output files
- if {$type != ".sps"} {
- regsub {^[ ]+([0-9]*[0-9]*[0-9]*[0-9])} $line {} line
- regsub {^ 0} $line {} line
- }
- # Get rid of braces.
- regsub -all {\{|\[} $line {(} line
- regsub -all {\}|\]} $line {)} line
- # Add a little indentation so that section marks show up better
- set line [string trimleft $line " "]
- set line " $line"
- if {[regsub { \*\*\*\* } $line {* } line]} {
- incr count -1
- } elseif {[regsub { \*\*\* } $line {• } line]} {
- incr count -1
- }
- if {[string length $line] > 35} {
- set line "[string range $line 0 35] ..."
- } else {
- # Get rid of trailing sem-colons.
- set line [string trimright $line ";" ]
- }
- }
- # If the mark starts with "execute", ignore it.
- if {![regexp {^ (execute|EXECUTE)} $line]} {
- setNamedMark $line $posBeg $posBeg $posBeg
- }
- set pos $posEnd
- }
- # Sorting the marks if this is a frequencies file.
- # (Code lifted from "sortMarksFile", in "marks.tcl")
- if {$type == ".freq"} {
- message "Sorting marks …"
- set mks {}
- foreach mk [getNamedMarks] {
- removeNamedMark -n [lindex $mk 0] -w [lindex $mk 1]
- lappend mks $mk
- }
- foreach mk [lsort $mks] {
- set name [lindex $mk 0]
- set disp [lindex $mk 2]
- set pos [lindex $mk 3]
- set end [lindex $mk 4]
-
- setNamedMark $name $disp $pos $end
- }
- message "This frequencies file describes $count variables."
- } else {
- message "This file contains $count commands."
- }
- }
-
- # ===========================================================================
- #
- # SPSS Parse Functions
- #
- # This will return only the SPSS command names.
- #
-
- proc SPSS::parseFuncs {} {
-
- global sortFuncsMenu
-
- if {[file extension [win::CurrentTail]] == ".sps" } {
- set funcExpr {^(\w+)}
- } elseif {[file tail [win::Current]] == "* SPSS Mode Example *"} {
- # Special case for Mode Examples folder
- set funcExpr {^(\w+)}
- } else {
- # Assume that it's output.
- set funcExpr {^([ ]+[0-9]+( )(0 )*)([a-zA-Z]+[a-zA-Z])}
- }
- set pos [minPos]
- set m {}
- while {[set match [search -s -f 1 -r 1 -i 0 -n $funcExpr $pos]] != ""} {
- if {[regexp -- $funcExpr [eval getText $match] "" "" "" "" word]} {
- lappend m [list $word [lindex $match 0]]
- }
- set pos [lindex $match 1]
- }
- if {$sortFuncsMenu} {
- regsub -all "\[\{\}\]" [lsort -ignore $m] "" m
- } else {
- regsub -all "\[\{\}\]" $m "" m
- }
- return $m
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ -------------------- ◊◊◊◊ #
- #
- # ◊◊◊◊ SPSS Menu ◊◊◊◊ #
- #
- # based upon the Stata menu, contributed by
- # L. Phillip Schumm <pschumm@uchicago.edu>
- #
-
- # Tell Alpha what procedures to use to build all menus, submenus.
-
- menu::buildProc spssMenu SPSS::buildMenu
- menu::buildProc spssHelp SPSS::buildHelpMenu
- menu::buildProc psppHelp SPSS::buildHelpMenu
- menu::buildProc spssKeywords SPSS::buildKeywordsMenu
- menu::buildProc markSpssFileAs… SPSS::buildMarkMenu
- menu::buildProc markPsppFileAs… SPSS::buildMarkMenu
-
- # First build the main SPSS menu.
-
- proc SPSS::buildMenu {} {
-
- global spssMenu SPSSmodeVars
-
- set app [SPSS::menuAppName]
- set lowApp [string tolower $app]
-
- set menuList [list \
- "${lowApp}HomePage" \
- "/S<U<OswitchTo${app}" \
- [list Menu -n ${lowApp}Help -M SPSS {}] \
- "(-" \
- [list Menu -n spssKeywords -M SPSS {}] \
- [list Menu -n mark${app}FileAs… -M SPSS {}] \
- "(-" \
- "/P<U<OprocessFile" \
- "/P<U<O<BprocessSelection" \
- "(-" \
- "/I<U<OinsertPath" \
- "(-" \
- "/N<U<BnextCommand" \
- "/P<U<BprevCommand" \
- "/S<U<BselectCommand" \
- "/I<B<OreformatCommand" \
- ]
- set submenus [list mark${app}FileAs… ${lowApp}Help spssKeywords]
- return [list build $menuList SPSS::menuProc $submenus $spssMenu]
- }
-
- # Manipulate the application's name for menu purposes.
-
- proc SPSS::menuAppName {{app ""}} {
-
- global SPSSmodeVars
-
- if {$app == ""} {
- set app [string toupper $SPSSmodeVars(application)]
- }
- if {$app == "SPSS"} {
- return "Spss"
- } else {
- return "Pspp"
- }
- }
-
- # Then build the "SPSS Help" submenu.
-
- proc SPSS::buildHelpMenu {} {
-
- global SPSSmodeVars SPSSPrefsInMenu alpha::platform
-
- # Determine which key should be used for "Help", with F8 as option.
-
- if {!$SPSSmodeVars(noHelpKey)} {
- set key "/t"
- } else {
- set key "/l"
- }
-
- # Reverse the local, www key bindings depending on the value of the
- # 'Local Help" variable.
-
- if {!$SPSSmodeVars(localHelp)} {
- set menuList [list \
- "${key}<OwwwCommandHelp…" \
- "${key}<IlocalCommandHelp…" \
- ]
- } else {
- set menuList [list \
- "${key}<OlocalCommandHelp…" \
- "${key}<IwwwCommandHelp…" \
- ]
- }
- lappend menuList "(-"
- if {$SPSSmodeVars(application) == "SPSS"} {
- lappend menuList "pspp"
- lappend menuList "!•spss"
- } else {
- lappend menuList "!•pspp"
- lappend menuList "spss"
- }
- lappend menuList "(-"
- if {${alpha::platform} == "alpha"} {
- set prefix "!√"
- } else {
- set prefix "!•"
- }
- foreach pref $SPSSPrefsInMenu {
- if {$SPSSmodeVars($pref)} {
- lappend menuList "${prefix}$pref"
- } else {
- lappend menuList "$pref"
- }
- }
- lappend menuList "(-"
- lappend menuList "setPsppApplication"
- lappend menuList "setSpssApplication"
- lappend menuList "(-"
- lappend menuList "${key}<BspssModeHelp"
-
- return [list build $menuList SPSS::helpProc {}]
- }
-
- # Then build the "SPSS Mode Keywords" submenu.
-
- proc SPSS::buildKeywordsMenu {} {
-
- set menuList [list \
- "listKeywords" \
- "checkKeywords" \
- "addNewCommands" \
- ]
- return [list build $menuList SPSS::keywordsProc {}]
- }
-
- # Then build the "Mark SPSS File As" submenu.
-
- proc SPSS::buildMarkMenu {} {
-
- global SPSSmodeVars alpha::platform
-
- set menuList [list \
- "source" \
- "output" \
- "freqFile" \
- "(-" \
- ]
- if {${alpha::platform} == "alpha"} {
- set prefix "!√"
- } else {
- set prefix "!•"
- }
- if {$SPSSmodeVars(autoMark)} {
- lappend menuList "${prefix}autoMark"
- } else {
- lappend menuList "autoMark"
- }
- return [list build $menuList SPSS::markFileProc {}]
- }
-
- proc SPSS::rebuildMenu {{menuName "spssMenu"} {pref ""}} {
- menu::buildSome $menuName
- }
-
- # Dim some menu items when there are no open windows.
- set menuItems {
- processFile processSelection markSpssFileAs markPsppFileAs
- insertPath
- nextCommand prevCommand selectCommand
- }
- foreach i $menuItems {
- hook::register requireOpenWindowsHook [list spssMenu $i] 1
- }
- unset i menuItems
-
- # Now we actually build the SPSS menu.
-
- menu::buildSome spssMenu
-
- # ===========================================================================
- #
- # ◊◊◊◊ SPSS menu support ◊◊◊◊ #
- #
-
- # This is the procedure called for all main menu items.
-
- proc SPSS::menuProc {menu item} {SPSS::$item}
-
- # Give a beta message for untested features / menu items.
-
- proc SPSS::betaMessage {{kill 1}} {
-
- beep ; message "Sorry, this feature has not been fully implemented."
- if {$kill} {return -code return}
- }
-
- # ===========================================================================
- #
- # Open the SPSS/PSPP Home Page
- #
-
- proc SPSS::spssHomePage {{app "SPSS"}} {
-
- global SPSSmodeVars
-
- if {$app == ""} {set app $SPSSmodeVars(application)}
- set lowApp [string tolower $app]
-
- url::execute $SPSSmodeVars(${lowApp}HomePage)
- }
-
- proc SPSS::psppHomePage {} {SPSS::spssHomePage "PSPP"}
-
- # ===========================================================================
- #
- # Switch to SPSS or PSPP application
- #
-
- proc SPSS::switchToSpss {{app "SPSS"}} {
-
- global SPSSmodeVars
-
- if {$app == ""} {set app $SPSSmodeVars(application)}
- app::launchFore [SPSS::sig $app]
- }
-
- proc SPSS::switchToPspp {} {SPSS::switchToSpss "PSPP"}
-
- # ===========================================================================
- #
- # Return the SPSS / PSPP signature.
- #
-
- proc SPSS::sig {{app "SPSS"}} {
-
- global SPSSmodeVars tcl_platform
-
- if {$app == ""} {set app $SPSSmodeVars(application)}
-
- set lowApp [string tolower $app]
- set capApp [string toupper $app]
- set pf $tcl_platform(platform)
-
- if {$pf == "macintosh"} {
- # Make sure that the Macintosh application for the signature exists.
- if {[catch {nameFromAppl $SPSSmodeVars(${lowApp}Sig)}]} {
- alertnote "Looking for the $capApp application ..."
- S::setApplication $lowApp
- }
- } elseif {$pf == "windows" || $pf == "unix"} {
- # Make sure that the Windows application for the signature exists.
- # We assume that this will work for unix, too.
- if {![file exists $SPSSmodeVars(${lowApp}Sig)]} {
- alertnote "Looking for the $capApp application ..."
- SPSS::setApplication $lowApp
- }
- }
- return $SPSSmodeVars(${lowApp}Sig)
- }
-
- # ===========================================================================
- #
- # Set Application
- #
- # Prompt the user to locate the local application for either SPSS or PSPP.
- #
-
- proc SPSS::setApplication {{app ""}} {
-
- global mode SPSSmodeVars
-
- if {$app == ""} {
- set app $SPSSmodeVars(application)
- }
- set lowApp [string tolower $app]
- set capApp [string toupper $app]
-
- set newSig ""
- set newSig [dialog::askFindApp $capApp $SPSSmodeVars(${lowApp}Sig)]
-
- if {$newSig != ""} {
- set SPSSmodeVars(${lowApp}Sig) "$newSig"
- set oldMode $mode
- set mode "SPSS"
- synchroniseModeVar "${lowApp}Sig" $SPSSmodeVars(${lowApp}Sig)
- set mode $oldMode
- message "The $capApp signature has been changed to \"$newSig\"."
- } else {
- message "Cancelled."
- }
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Help ◊◊◊◊ #
- #
-
- proc SPSS::helpProc {menu item} {
-
- global SPSSmodeVars SPSSPrefsInMenu
-
- if {$item == "wwwCommandHelp"} {
- SPSS::wwwCommandHelp
- } elseif {$item == "localCommandHelp"} {
- SPSS::localCommandHelp
- } elseif {$item == "pspp" || $item == "spss"} {
- SPSS::selectApplication $item
- SPSS::rebuildMenu
- } elseif {[lsearch -exact $SPSSPrefsInMenu $item] != -1} {
- SPSS::flagFlip $item
- SPSS::rebuildMenu spssHelp
- SPSS::rebuildMenu psppHelp
- } elseif {$item == "setSpssApplication"} {
- SPSS::setApplication "SPSS"
- } elseif {$item == "setPsppApplication"} {
- SPSS::setApplication "SPSS"
- } elseif {$item == "spssModeHelp"} {
- package::helpFile "SPSS"
- } else {
- SPSS::$item
- }
- }
-
- # Choose between SPSS and PSPP
-
- proc SPSS::selectApplication {app} {
-
- global mode SPSSmodeVars
-
- set app [string toupper $app]
-
- set oldMode $mode
- set mode "SPSS"
- set SPSSmodeVars(application) $app
- set mode $oldMode
- synchroniseModeVar application $SPSSmodeVars(application)
- message "Default application is now $app."
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Keywords ◊◊◊◊ #
- #
-
- proc SPSS::keywordsProc {menuName item} {
-
- global SPSSlowerCaseCmds
-
- if {$item == "listKeywords"} {
- set keywords [listpick -l -p "Current SPSS mode keywords…" $SPSSlowerCaseCmds]
- foreach keyword $keywords {
- SPSS::checkKeywords $keyword
- }
- } elseif {$item == "addNewCommands" || $item == "addNewOptions"} {
- set item [string trimleft $item "addNew"]
- if {$item == "Commands" && [llength [winNames]] && [askyesno \
- "Would you like to add all of the \"extra\" commands from this window\
- to the \"Add Commands\" preference?"] == "yes"} {
- SPSS::addWindowCommands
- } else {
- SPSS::addKeywords $item
- }
- } else {
- SPSS::$item
- }
- }
-
- # ===========================================================================
- #
- # SPSS::addWindowCommands
- #
- # Add all of the "extra" commands which appear in entries in this window.
- #
-
- proc SPSS::addWindowCommands {} {
-
- global mode SPSScmds SPSSmodeVars
-
- if {![llength [winNames]]} {
- message "Cancelled -- no current window!"
- return
- }
-
- message "Scanning [win::CurrentTail] for all commands…"
-
- set pos [minPos]
- set pat {^([a-zA-Z0-9]+[a-zA-Z0-9])+[\t ]}
- while {![catch {search -f 1 -r 1 $pat $pos} match]} {
- set pos [nextLineStart [lindex $match 1]]
- set commandLine [getText [lindex $match 0] [lindex $match 1]]
- regexp $pat $commandLine match aCommand
- set aCommand [string tolower $aCommand]
- if {![lcontains SPSScmds $aCommand]} {
- append SPSSmodeVars(addCommands) " $aCommand"
- }
- }
- set SPSSmodeVars(addCommands) [lsort [lunique $SPSSmodeVars(addCommands)]]
- set oldMode $mode
- set mode "SPSS"
- synchroniseModeVar addCommands $SPSSmodeVars(addCommands)
- set mode $oldMode
- if {[llength $SPSSmodeVars(addCommands)]} {
- SPSS::colorizeSPSS
- listpick -p "The \"Add Commands\" preference includes:" \
- $SPSSmodeVars(addCommands)
- message "Use the \"Mode Prefs --> Preferences\" menu item to edit keyword lists."
- } else {
- message "No \"extra\" commands from this window were found."
- }
- }
-
- proc SPSS::addKeywords {{category} {keywords ""}} {
-
- global mode SPSSmodeVars
-
- if {$keywords == ""} {
- set keywords [prompt "Enter new SPSS $category:" ""]
- }
-
- # The list of keywords should all be lower case.
- set keywords [string tolower $keywords]
- # Check to see if the keyword is already defined.
- foreach keyword $keywords {
- set checkStatus [SPSS::checkKeywords $keyword 1 0]
- if {$checkStatus != 0} {
- alertnote "Sorry, \"$keyword\" is already defined\
- in the $checkStatus list."
- message "Cancelled."
- return -code return
- }
- }
- # Keywords are all new, so add them to the appropriate mode preference.
- lappend SPSSmodeVars(add$category) $keywords
- set SPSSmodeVars(add$category) [lsort $SPSSmodeVars(add$category)]
- set oldMode $mode
- set mode "SPSS"
- synchroniseModeVar add$category $SPSSmodeVars(add$category)
- set mode $oldMode
- SPSS::colorizeSPSS
- message "\"$keywords\" added to $category preference."
- }
-
- proc SPSS::checkKeywords {{newKeywordList ""} {quietly 0} {noPrefs 0}} {
-
- global SPSSmodeVars
-
- global SPSSmodeVars SPSSCommands SPSSUserCommands SPSSFunctions SPSSOperators
-
- set type 0
- if {$newKeywordList == ""} {
- set quietly 0
- set newKeywordList [prompt "Enter SPSS mode keywords to be checked:" ""]
- }
- # Check to see if the new keyword(s) is already defined.
- foreach newKeyword $newKeywordList {
- set newKeyword [string tolower $newKeyword]
- if {[lsearch -exact $SPSSCommands $newKeyword] != "-1"} {
- set type SPSSCommands
- } elseif {[lsearch -exact $SPSSUserCommands $newKeyword] != "-1"} {
- set type SPSSUserCommands
- } elseif {[lsearch -exact $SPSSmodeVars(addCommands) $newKeyword] != "-1"} {
- set type SPSSmodeVars(addCommands)
- } elseif {!$noPrefs && \
- [lsearch -exact $SPSSFunctions $newKeyword] != "-1"} {
- set type SPSSFunctions
- } elseif {!$noPrefs && \
- [lsearch -exact $SPSSOperators $newKeyword] != "-1"} {
- set type SPSSOperators
- }
- if {$quietly} {
- # When this is called from other code, it should only contain
- # one keyword to be checked, and we'll return it's type.
- return "$type"
- } elseif {!$quietly && $type == 0} {
- alertnote "\"$newKeyword\" is not currently defined\
- as a SPSS mode keyword"
- } elseif {$type != 0} {
- # This will work for any other value for "quietly", such as 2
- alertnote "\"$newKeyword\" is currently defined as a keyword\
- in the \"$type\" list."
- }
- set type 0
- }
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Processing ◊◊◊◊ #
- #
-
- # ===========================================================================
- #
- # Process File
- #
- # Send entire file to SPSS for processing, adding carriage return at end
- # of file if necessary.
- #
- # Optional "f" argument allows this to be called by other code, or to be
- # sent via a Tcl shell window.
- #
-
- proc SPSS::processFile {{f ""} {app ""}} {
-
- global SPSSmodeVars
-
- if {$f != ""} {file::openAny $f}
- set f [win::Current]
-
- if {$app == ""} {set app $SPSSmodeVars(application)}
-
- set lowApp [string tolower $app]
- set capApp [string toupper $app]
-
- set dirtyWindow [winDirty]
- set dontSave 0
- if {$dirtyWindow && [askyesno \
- "Do you want to save the file before sending it to $capApp?"] == "yes"} {
- save
- } else {
- set dontSave 1
- }
- if {!$dontSave && [lookAt [pos::math [maxPos] - 1]] != "\r"} {
- set pos [getPos]
- goto [maxPos]
- insertText "\r"
- goto $pos
- alertnote "Carriage return added to end of file."
- save
- }
-
- app::launchBack '[SPSS::sig $capApp]'
- sendOpenEvent noReply '[SPSS::sig $capApp]' $f
- switchTo '[SPSS::sig $capApp]'
- }
-
-
- # ===========================================================================
- #
- # Process Selection
- #
- # Procedure to implement transfer of selected lines to SPSS for processing.
- #
-
- proc SPSS::processSelection {{selection ""} {app ""}} {
-
- global PREFS SPSSmodeVars
-
- if {$app == ""} {set app $SPSSmodeVars(application)}
-
- set lowApp [string tolower $app]
- set capApp [string toupper $app]
-
- if {$selection == ""} {
- if {![isSelection]} {
- message "No selection -- cancelled."
- return
- } else {
- set selection [getSelect]
- }
- }
- file::ensureDirExists [file join $PREFS SPSS-tmp]
- set newFile [file join $PREFS SPSS-tmp temp-SPSS.s]
- file::writeAll $newFile $selection 1
-
- app::launchBack '[SPSS::sig $capApp]'
- sendOpenEvent noReply '[SPSS::sig $capApp]' $newFile
- switchTo '[SPSS::sig $capApp]'
- }
-
- proc SPSS::quitHook {} {temp::cleanup SPSS-tmp}
-
- # ===========================================================================
- #
- # ◊◊◊◊ Marks ◊◊◊◊ #
- #
-
- proc SPSS::markFileProc {menu item} {
-
- if {$item == "source"} {
- SPSS::MarkFile {.sps}
- } elseif {$item == "output"} {
- # doesn't really matter what we put for the mark file "type" here,
- # since output is the default if other "if ..." cases aren't met.
- SPSS::MarkFile {.out}
- } elseif {$item == "freqFile"} {
- SPSS::MarkFile {.freq}
- } elseif {$item == "autoMark"} {
- SPSS::flagFlip autoMark
- SPSS::rebuildMenu markSpssFileAs…
- SPSS::rebuildMenu markPsppFileAs…
- }
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Insertions ◊◊◊◊ #
- #
-
- proc SPSS::insertPath {} {
-
- global file::separator
-
- set path ""
- set t ""
- append t "\"${file::separator}"
- set path [getfile "Choose path of target file:"]
- if {$path != ""} {
- append t $path
- append t "\""
- insertText $t
- }
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ Navigation ◊◊◊◊ #
- #
-
- # Next/Prev command can simply return the position of the next command
- # (quietly == 1), move the cursor to the next command (placing the cursor
- # at the top of the window if toTop == 1), extend the current selection to
- # the end of the this command, or (if the current command is already
- # highlighted in its entirety) extend the current selection to the end of
- # the next command.
- #
-
- proc SPSS::nextCommand {{quietly 0} {toTop 0}} {
-
- if {[pos::compare [selEnd] == [maxPos]]} {
- set pos [maxPos]
- } else {
- set pos [pos::math [selEnd] + 1]
- }
- set pat {^[^\r\n\t \*/]}
-
- if {![catch {search -f 1 -r 1 $pat $pos} match]} {
- set pos [lineStart [lindex $match 1]]
- } else {
- set pos [maxPos]
- }
- if {$quietly} {
- return $pos
- } elseif {[isSelection]} {
- set limit1 [lindex [SPSS::getCommand [selEnd]] 1]
- set limit2 [lindex [SPSS::getCommand $pos ] 1]
- if {$limit2 == "-1"} {set limit2 [maxPos]}
- if {$limit1 == "-1"} {set limit1 $limit2}
- if {[pos::compare [selEnd] < $limit1]} {
- select [getPos] $limit1
- } else {
- select [getPos] $limit2
- }
- } elseif {$pos == [maxPos]} {
- message "No further commands in the file."
- return
- } else {
- goto $pos
- message [getText $pos [nextLineStart $pos]]
- }
- if {$toTop} {insertToTop}
- }
-
- proc SPSS::prevCommand {{quietly 0} {toTop 0}} {
-
- if {[pos::compare [getPos] == [minPos]]} {
- set pos [minPos]
- } else {
- set pos [pos::math [getPos] - 1]
- }
- set pat {^[^\r\n\t \*/]}
-
- if {![catch {search -f 0 -r 1 $pat $pos} match]} {
- set pos [lineStart [lindex $match 1]]
- } else {
- set pos [minPos]
- }
- if {$quietly} {
- return $pos
- } elseif {[isSelection]} {
- # Going backwards is actually easier with selections.
- select $pos [selEnd]
- } elseif {$pos == [minPos]} {
- message "No further commands in the file."
- return
- } else {
- goto $pos
- message [getText $pos [nextLineStart $pos]]
- }
- if {$toTop} {insertToTop}
- return $pos
- }
-
- proc SPSS::selectCommand {} {
-
- set pos [getPos]
- set limits [SPSS::getCommand $pos]
- set posBeg [lindex $limits 0]
- set posEnd [lindex $limits 1]
-
- if {$posBeg != "-1" && $posEnd != "-1" && \
- [pos::compare $pos >= $posBeg] && [pos::compare $pos <= $posEnd]} {
- select $posBeg $posEnd
- } else {
- message "The cursor is not within a command."
- error "The cursor is not within a command."
- }
- }
-
- proc SPSS::copyCommand {{quietly 0}} {
-
- set pos [getPos]
- if {[set posBeg [lindex [SPSS::getCommand $pos] 0]] != "-1"} {
- goto $posBeg
- forwardWord
- set posEnd [getPos]
- if {!$quietly} {
- select $posBeg $posEnd
- copy
- message "\"[getText $posBeg $posEnd]\" copied to clipboard."
- }
- goto $pos
- return [getText $posBeg $posEnd]
- } elseif {!$quietly} {
- message "The cursor is not within a command."
- }
- return ""
- }
-
- proc SPSS::reformatCommand {} {
-
- if {![isSelection]} {SPSS::selectCommand}
- message "Reformatting …"
- ::indentRegion
- goto [pos::math [getPos] -1]
- goto [SPSS::nextCommand 1]
- message "Reformatted."
- }
-
- proc SPSS::getCommand {pos} {
-
- set pos1 [pos::math [nextLineStart $pos] - 1]
- set pat {^[^\r\n\t \}\)]}
- set posBeg "-1"
- set posEnd "-1"
- if {![catch {search -f 0 -r 1 $pat $pos1} match]} {
- set posBeg [lindex $match 0]
- set pos2 [nextLineStart $posBeg]
- if {![catch {search -f 1 -r 1 $pat $pos2} match]} {
- set posEnd [lindex $match 0]
- } else {
- set posEnd [maxPos]
- }
- # Now back up to remove empty or commented lines.
- set posEndPrev [pos::math $posEnd - 1]
- set prevLine [getText [lineStart $posEndPrev] $posEndPrev]
- while {[regexp {^[\t ]*$} $prevLine]} {
- set posEnd [lineStart $posEndPrev]
- set posEndPrev [pos::math $posEnd - 1]
- set prevLine [getText [lineStart $posEndPrev] $posEndPrev]
- }
- }
- return [list $posBeg $posEnd]
- }
-
- # ===========================================================================
- #
- # ◊◊◊◊ --------------------- ◊◊◊◊ #
- #
- # ◊◊◊◊ version history ◊◊◊◊ #
- #
- # modified by vers# reason
- # -------- --- ------ -----------
- # 01/28/20 cbu 1.0.1 First created SPSS mode, based upon other modes found
- # in Alpha's distribution. Commands are based on
- # version 4.0 of SPSS.
- # 03/02/20 cbu 1.0.2 Minor modifications to comment handling.
- # 03/20/00 cbu 1.0.3 Minor update of keywords dictionaries.
- # 04/01/00 cbu 1.0.4 Added new preferences to allow the user to enter
- # additional commands, arguments, and symbols.
- # Added "Update Colors" proc to avoid need for a restart
- # 04/08/00 cbu 1.0.5 Unset obsolete preferences from earlier versions.
- # Added "Continue Comment", "Electric Return Over-ride",
- # and "Electric Period".
- # Renamed "Update Colors" to "Update Preferences".
- # 04/16/00 cbu 1.1 Renamed to spssMode.tcl
- # Added "Mark File" and "Parse Functions" procs.
- # 06/22/00 cbu 1.2 "Mark File" now recognizes headings as well as commands.
- # "Mark File" recognizes source or output files.
- # Completions, Completions Tutorial added.
- # "Reload Completions", referenced by "Update Preferences".
- # Better support for user defined keywords.
- # Removed "Continue Comment", now global in Alpha 7.4.
- # Added command double-click for on-line help.
- # <shift, control>-<command> double-click syntax info.
- # (Foundations, at least. Ongoing project.)
- # 08/08/00 cbu 1.2.1 Minor electric completions bug fixes.
- # Added message if no matching ")".
- # Mark File ignores "execute" commands.
- # Mark File can mark a frequencies file.
- # Beta-version of an SPSS menu, based on the Stata menu.
- # Added "spssSig" preference to allow user to find
- # local application if necessary.
- # Added SPSS::sig which returns SPSS signature.
- # 08/28/00 cbu 1.2.2 Added some of the flag preferences to "SPSS Help" menu.
- # Added "flagFlip" to update preference bullets in menu.
- # Added a "noHelpKey" preference, which switches the
- # "help" key binding to F8.
- # Added "Add New Commands / Arguments" to "SPSS Help" menu.
- # Added "Set SPSS Application to "SPSS Help" menu.
- # 11/05/00 cbu 1.3 Added "next/prevCommand", "selectCommand", and
- # "copyCommand" procs to menu.
- # Added "SPSS::indentLine".
- # Added "SPSS::reformatCommand" to menu.
- # "SPSS::reloadCompletions" is now obsolete.
- # "SPSS::updatePreferences" is now obsolete.
- # "SPSS::colorizeSPSS" now takes care of setting all
- # keyword lists, including SPSScmds.
- # Cleaned up completion procs. This file never has to be
- # reloaded. (Similar cleaning up for "SPSS::DblClick").
- # 11/16/00 cbu 2.0 New url prefs handling requires 7.4b21
- # Added "Home Page" pref, menu item.
- # Removed hook::register requireOpenWindowsHook from
- # mode declaration, put it after menu build.
- # 12/19/00 cbu 2.1 The menu proc "Add Commands" now includes an option
- # to grab all of the "extra" command from the current
- # window, using SPSS::addWindowCommands.
- # Added "Keywords" submenu, "List Keywords" menu item.
- # Big cleanup of ::sig, ::setApplication, processing ...
- # 01/25/01 cbu 2.1.1 Bug fix for SPSS::processSelection/File.
- # Better frequency file marking.
- # Bug fix for comment characters.
- #
-
- # ===========================================================================
- #
- # .
-